import Parser = require('./../base/Parser');
import GCJ_CLASS_TYPE = require('./../../common/GCJ_CLASS_TYPE');
import Point = require('./../../common/graph/Point');
import CompoundPath = require('./../../common/graph/CompoundPath');
import PointPath = require('./../../common/graph/PointPath');
import ObjBase=require('./ObjBase');
import GroupObj=require('./GroupObj');
import GraphObj=require('./GraphObj');
import TextObj=require('./TextObj');
import FColor=require('./../color/FColor');
import FColorBase=require('./../color/FColorBase');
import ObjPosition=require('./../base/ObjPosition');
import SJGXY = require('./../replace/SJGXY');
import DEFINE = require('./../../common/DEFINE');
import PageInfo=require('./../../common/PageInfo');
import SJGReplaceGroup = require('./../replace/SJGReplaceGroup');
import SJGReplaceItemBase=require('./../replace/SJGReplaceItemBase');
import SJGReplaceItemChart=require('./../replace/SJGReplaceItemChart');
import FColorConverter=require('./../color/FColorConverter');
import ImageObj=require('./ImageObj');
import ChartApperanceBase=require('./apperance/ChartApperanceBase');
import ChartApperanceLine=require('./apperance/ChartApperanceLine');
import ChartApperanceBar=require('./apperance/ChartApperanceBar');
import ChartApperancePie=require('./apperance/ChartApperancePie');

var path=require('path');
var common_CommonUtil=require('../../../../common/util/CommonUtil');
var CommonUtil=require('./../../../util/CommonUtil');
var FileDownLoader=require('../../../../common/util/FileDownLoader');
var async  = require( 'async'); // 同步控制
var fs = require('fs')
var CONFIG=require('../../../../common/config');

export = ChartObj;
    

/**
 *
 * @author 
 *
 */
class ChartObj extends GroupObj {
    // 示例图
    public source: string="";// 废弃
    public image: ObjPosition=new ObjPosition();// 废弃

    // 40折线图／41柱状图／42饼状图
    public type: number=0;

    // 风格: 0普通 等等
    public manner: number=0;

    //    x轴名称／y轴名称
    public xName: string="";
    public yName: string="";
    // 刻度线，当type为40折线图／41柱状图时有效
    public curve: SJGXY=new SJGXY();
    // 数据组
    public dataGroups: Array<SJGXY>=new Array<SJGXY>();
    // 数据源
    public from: string="";
    // 图表外观
    public apperance: ChartApperanceBase=null;


    public constructor(g?) {
        super(g);

        this.ct=GCJ_CLASS_TYPE.CLASS_TYPE_ChartObj;
    }
    // 添加默认数据
    public initData() {
        this.xName="x轴名称";
        this.yName="y轴名称";
        this.from="数据来源";
        this.name="图表名称";
        if(this.type==SJGReplaceItemBase.TYPE_LINE_CHART) {
            this.curve.x=['1','2','3','4'];
            this.curve.y=['1','2','3'];
            this.dataGroups.push(SJGXY.from(['1','2','3'],['1','2','2.5']));
            this.apperance=new ChartApperanceLine();
        } else if(this.type==SJGReplaceItemBase.TYPE_BAR_CHART) {
            this.curve.x=['1','2','3','4'];
            this.curve.y=['1','2','3'];
            this.dataGroups.push(SJGXY.from(['1','2','3','4'],['1','2','2.5','1.5']));
            this.apperance=new ChartApperanceBar();
        } else {
            this.dataGroups.push(SJGXY.from(['1','2','3','4'],['1','2','2.5','0.9']));
            this.apperance=new ChartApperancePie();
        }

    }

    // 从json对象(注意不是json字符串)中解析
    // 参数：self,true表示只拷贝自身数据，而不拷贝子的数据
    public fromJson(jsonObj,versionId,self?) {
        super.fromJson(jsonObj,versionId,self);

        // 废弃
        //        this.source = jsonObj.source;
        //        if(jsonObj.hasOwnProperty("image")) {
        //            this.image.fromJson(jsonObj.image,versionId);
        //        }

        this.type=jsonObj.type;
        if(jsonObj.hasOwnProperty("manner")) {
            this.manner=jsonObj.manner;
        }

        if(jsonObj.hasOwnProperty("xName")) {
            this.xName=jsonObj.xName;
        }
        if(jsonObj.hasOwnProperty("yName")) {
            this.yName=jsonObj.yName;
        }
        if(jsonObj.hasOwnProperty("curve")) {
            this.curve.fromJson(jsonObj.curve,versionId);
        }

        if(jsonObj.hasOwnProperty('dataGroups')) {
            for(var i=0;i<jsonObj.dataGroups.length;i++) {
                var xy=new SJGXY();
                xy.fromJson(jsonObj.dataGroups[i],versionId);
                this.dataGroups.push(xy);
            }
        }

        if(jsonObj.hasOwnProperty("from")) {
            this.from=jsonObj.from;
        }
        if(jsonObj.hasOwnProperty("apperance")) {
            this.apperance=Parser.fromUnknownJson(jsonObj.apperance,versionId,this.getGlobalData());
        }


        // 加载文档时
        if(this.getGlobalData().docStatus()==DEFINE.DOC_STATUS_LOADING) {
            this.getGlobalData().objManager().saveObject(this);
        }

    }
    // 转成json字符串
    public toJson(): string {
        // 去掉父json字符串的头尾
        var superJson=super.toJson();
        superJson=superJson.substr(1,superJson.length-2);

        var ret='{';
        ret+=superJson;

        // 废弃
        // source
        //        ret += ',';
        //        ret += '"source":' + '"';
        //        ret += this.source + '"';

        // 废弃
        // image
        //        ret += ',';
        //        ret += '"image":';
        //        ret += this.image.toJson();

        // type
        ret+=',';
        ret+='"type":';
        ret+=this.type;

        // manner
        ret+=',';
        ret+='"manner":';
        ret+=this.manner;

        // xName
        ret+=',';
        ret+='"xName":'+'"';
        ret+=this.xName+'"';
        // yName
        ret+=',';
        ret+='"yName":'+'"';
        ret+=this.yName+'"';

        // curve
        if(this.curve!=null) {
            ret+=',';
            ret+='"curve":'+this.curve.toJson();
        }

        // dataGroups
        ret+=',';
        ret+='"dataGroups":[';
        for(var i=0;i<this.dataGroups.length;i++) {
            if(i>0) {
                ret+=',';
            }
            ret+=this.dataGroups[i].toJson();
        }
        ret+=']';

        // from
        ret+=',';
        ret+='"from":'+'"';
        ret+=this.from+'"';

        // apperance
        if(this.apperance) {
            ret+=',';
            ret+='"apperance":'+this.apperance.toJson();
        }

        ret+='}';
        return ret;
    }

    // 获取对象名称
    public getObjetName(): string {
        var objNm="图表";
        switch(this.type) {
            case 40: objNm+="[折线图]"; break;
            case 41: objNm+="[柱状图]"; break;
            case 42: objNm+="[饼状图]"; break;
        }
        return objNm;
    }

    // 当作普通对象处理（如：拖入编组操作时）
    public isSimple(): boolean {
        return true;
    }

    // 扩展大小
    // 参数：controlType 控制点类型
    // 参数：ratioX x缩放比例
    // 参数：ratioY y缩放比例
    // 参数：outside true表示操作所在的最外层对象，false表示内部对象
    public expand(controlType: number,ratioX: number,ratioY: number,outside: boolean) {
        super.expand(controlType,ratioX,ratioY,outside);

        //        if(this.constrain.scale==1) {
        //            this.image=this.pos.adjust(this.image.w,this.image.h);
        //        }
    }

    // 常量定义
    public static BAR_ORIGIN_X: number=40; // 横轴的起始点和终止点
    public static BAR_ORIGIN_Y: number=-40;

    public static H_BAR_X_END: number=-40;// 负数表示倒数
    public static V_BAR_Y_END: number=-40;// 负数表示倒数

    public static H_BAR_CURVE_TEXT_GAP: number=10; // 横轴离开开度文字的距离
    public static V_BAR_CURVE_TEXT_GAP: number=20; // 纵轴离开开度文字的距离
    public static BAR_DISTANCE_OF_END_AND_MARK: number=50; // 轴的端点离开最后一个Mark的距离

    public static MARK_LEN: number=10; // 刻度的长度

    public static NAME_Y: number=10;            // 表名的Y坐标
    public static NAME_H: number=30;            // 表名的高度

    public static FROM_Y: number=-0;            // 数据来源的Y坐标

    public static CURVE_STROKE_WIDTH: number=1;      // 刻度线的宽度
    public static ASSIST_STROKE_WIDTH: number=0.5;      // 辅助线线的宽度
    public static LINE_STROKE_WIDTH: number=4;      // 折线线的宽度
    public static LINE_POINT_CIRCLE_WIDTH: number=30;      // 折线上坐标点的宽度

    public static BAR_STROKE_WIDTH: number=40;      // 柱状图的宽度


    public static CATEGORY_X_START: number=-60;           // 分类备注的起始点和终止点
    public static CATEGORY_Y_START: number=30;            // 分类备注的起始点和终止点


    public static SECTOR_MARGIN: number=30;// 饼状图的边距
    public static SECTOR_MIN_R: number=30;// 饼状图的最小直径
    public static SECTOR_R_W: number=20;// 饼状图的圈的宽度
    public static SECTOR_SEP_STROKE_WIDTH: number=5;      // 柱状图的宽度
    public static SECTOR_CATEGORY_GAP: number=25;      // 柱状图的分类描述离饼子的距离
    public static SECTOR_CATEGORY_LINE_SPACE: number=15;      // 柱状图的多个分类描述距离
    public static SECTOR_CATEGORY_RECT_WIDTH: number=20;      // 柱状图的多个分类描述中的正方形色块尺寸
    public static SECTOR_CATEGORY_RECT_TEXT_GAP: number=10;      // 柱状图的正方形色块与文字的距离

    // 取得步长
    // 参数：isX true取得x的步长，false去的y的步长
    public getStep(isX: Boolean=true): number {
        var lineLen=this.getAxisLen(isX);
        if(isX) {
            var len: number=this.curve.x.length+1;
            var step=Math.ceil(lineLen/len);
            return step;
        } else {
            var len: number=this.curve.y.length;
            var step=Math.ceil(lineLen/len);
            return step;
        }
    }
    // 取得坐标轴长度
    // 参数：isX true取得x的步长，false去的y的步长
    public getAxisLen(isX: Boolean=true): number {
        if(isX) {
            var lineLen: number=(ChartObj.H_BAR_X_END+this.pos.w-ChartObj.BAR_ORIGIN_X)-ChartObj.BAR_DISTANCE_OF_END_AND_MARK;
            return lineLen;
        } else {
            var lineLen: number=(ChartObj.V_BAR_Y_END+this.pos.h+ChartObj.BAR_ORIGIN_Y)-ChartObj.BAR_DISTANCE_OF_END_AND_MARK;
            return lineLen;
        }
    }

    // 横轴＋刻度＋刻度数值
    public createHorizonBar(bar: Boolean=false) {
        var app: ChartApperanceLine=<ChartApperanceLine>this.apperance;
        if(!app) return;

        // 创建编组，起点为坐标轴原点,宽度为坐标轴长度
        var groupObj: GroupObj=new GroupObj(this.getGlobalData());
        groupObj.pos=new ObjPosition(ChartObj.BAR_ORIGIN_X,this.pos.h+ChartObj.BAR_ORIGIN_Y,
            this.pos.w+ChartObj.H_BAR_X_END-ChartObj.BAR_ORIGIN_X,this.pos.h+ChartObj.V_BAR_Y_END+ChartObj.BAR_ORIGIN_Y);
        this.getGlobalData().objManager().saveObject(groupObj);
        this.addChild(groupObj,this.children.length);


        // 坐标原点
        var textObj: TextObj=new TextObj(this.getGlobalData());
        textObj.pos=new ObjPosition(-ChartObj.H_BAR_CURVE_TEXT_GAP,ChartObj.H_BAR_CURVE_TEXT_GAP,50,50);// this.pos.w,this.pos.h
        textObj.te="0";
        textObj.fs=this.apperance.font_style.fs;
        textObj.fn=this.apperance.font_style.fn;
        textObj.fz=TextObj.FONT_ZOOM_FACTOR;
        textObj.color=FColor.lightGrayColor();
        this.getGlobalData().objManager().saveObject(textObj);
        groupObj.addChild(textObj,groupObj.children.length);

        // 步长
        var len: number=this.curve.x.length;
        var step=this.getStep(true);

        // 横轴
        if(app.x.axis.v==1) {
            // 横轴建立图形对象
            var cp: CompoundPath=new CompoundPath();
            var path: PointPath=new PointPath();
            cp.paths.push(path);
            path.points.push(new Point(0,0,Point.POD_TT_PRIM_MOVE));
            path.points.push(new Point(groupObj.pos.w,0,Point.POD_TT_PRIM_LINE));

            var graphObj: GraphObj=new GraphObj(this.getGlobalData());
            graphObj.pos=new ObjPosition(0,0,groupObj.pos.w,this.pos.h);
            graphObj.cp=cp;
            graphObj.strokewidth=app.x.axis.w;
            graphObj.strokecolor=app.x.axis.color;
            this.getGlobalData().objManager().saveObject(graphObj);
            groupObj.addChild(graphObj,groupObj.children.length);

            // 尖头
            //        var path: PointPath=new PointPath();
            //        cp.paths.push(path);
            //        path.points.push(new Point(ChartObj.H_BAR_X_END+this.pos.w-10,5,Point.POD_TT_PRIM_MOVE));
            //        path.points.push(new Point(ChartObj.H_BAR_X_END+this.pos.w,0,Point.POD_TT_PRIM_LINE));
            //
            //        var path: PointPath=new PointPath();
            //        cp.paths.push(path);
            //        path.points.push(new Point(ChartObj.H_BAR_X_END+this.pos.w-10,-5,Point.POD_TT_PRIM_MOVE));
            //        path.points.push(new Point(ChartObj.H_BAR_X_END+this.pos.w,0,Point.POD_TT_PRIM_LINE));

            // 大刻度的文字，对象起点放在（curveX，坐标原点的y+ChartObj.BAR_CURVE_TEXT_GAP）
            var xLabelOffset=bar? -step/2:0;
            for(var i=0;i<len;i++) {
                var textObj: TextObj=new TextObj();
                //textObj.pos=new ObjPosition((i+1)*step,ChartObj.H_BAR_CURVE_TEXT_GAP,this.pos.w,this.pos.h);
                // 文字尽量中心对齐刻度线 modified [2016-05-09]
                textObj.pos=new ObjPosition(xLabelOffset+(i+1)*step-8*(this.curve.x[i].trim().length),
                    ChartObj.H_BAR_CURVE_TEXT_GAP,this.pos.w/2,50);// this.pos.w,this.pos.h
                textObj.te=this.curve.x[i].trim();
                textObj.fs=app.font_style.fs;
                textObj.fn=app.font_style.fn;
                textObj.fz=TextObj.FONT_ZOOM_FACTOR;
                textObj.color=app.font_style.color;
                this.getGlobalData().objManager().saveObject(textObj);
                groupObj.addChild(textObj,groupObj.children.length);
            }


            // x轴名称
            //            if(this.xName) {
            //                var textObj: TextObj=new TextObj(this.getGlobalData());
            //                //textObj.pos=new ObjPosition(groupObj.pos.w,ChartObj.H_BAR_CURVE_TEXT_GAP,this.pos.w,this.pos.h);
            //                // 放到x轴上方 modified [2016-05-09]
            //                textObj.pos=new ObjPosition(groupObj.pos.w+ChartObj.H_BAR_CURVE_TEXT_GAP,
            //                    -ChartObj.H_BAR_CURVE_TEXT_GAP*3,this.pos.w/2,50);// this.pos.w,this.pos.h
            //                textObj.te=this.xName;
            //                textObj.fs=app.font_style.fs;
            //                textObj.fn=app.font_style.fn;
            //                textObj.fz=TextObj.FONT_ZOOM_FACTOR;
            //                textObj.color=app.font_style.color;
            //                this.getGlobalData().objManager().saveObject(textObj);
            //                groupObj.addChild(textObj,groupObj.children.length);
            //            }
        }

        // 纵轴辅助线
        if(app.y.axis_assist.v==1) {
            // 横轴建立图形对象
            var cp: CompoundPath=new CompoundPath();
            for(var i=0;i<len;i++) {
                // 大刻度
                //            var path: PointPath=new PointPath();
                //            cp.paths.push(path);
                //            path.points.push(new Point((i+1)*step,-ChartObj.MARK_LEN,Point.POD_TT_PRIM_MOVE));
                //            path.points.push(new Point((i+1)*step,0,Point.POD_TT_PRIM_LINE));

                var path: PointPath=new PointPath();
                cp.paths.push(path);
                path.points.push(new Point((i+1)*step,-groupObj.pos.h,Point.POD_TT_PRIM_MOVE));
                path.points.push(new Point((i+1)*step,0,Point.POD_TT_PRIM_LINE));
            }

            var graphObj: GraphObj=new GraphObj(this.getGlobalData());
            graphObj.pos=new ObjPosition(0,0,groupObj.pos.w,this.pos.h);
            graphObj.cp=cp;
            graphObj.strokewidth=app.y.axis_assist.w;
            graphObj.strokecolor=app.y.axis_assist.color;
            this.getGlobalData().objManager().saveObject(graphObj);
            groupObj.addChild(graphObj,groupObj.children.length);

        }


    }
    // 计算水平虚线
    // 参数：y
    // 参数：w 虚线长度
    // 参数：lineW 实线长度
    // 参数：gap 空格长度
    public dashLineH(y: number,w: number,lineW: number,gap: number): Array<PointPath> {
        var ret: Array<PointPath>=new Array<PointPath>();
        var curX: number=0;
        while(curX<w) {
            var path: PointPath=new PointPath();
            path.points.push(new Point(curX,y,Point.POD_TT_PRIM_MOVE));
            path.points.push(new Point(curX+lineW,y,Point.POD_TT_PRIM_LINE));
            curX+=(lineW+gap);

            ret.push(path);
        }
        return ret;
    }


    //        纵轴＋刻度＋刻度数值
    public createVerticalBar() {
        var app: ChartApperanceLine=<ChartApperanceLine>this.apperance;
        if(!app) return;

        // 创建编组，起点为坐标轴原点,宽度为坐标轴长度
        var groupObj: GroupObj=new GroupObj(this.getGlobalData());
        groupObj.pos=new ObjPosition(ChartObj.BAR_ORIGIN_X,this.pos.h+ChartObj.BAR_ORIGIN_Y,
            this.pos.w+ChartObj.H_BAR_X_END-ChartObj.BAR_ORIGIN_X,this.pos.h+ChartObj.V_BAR_Y_END+ChartObj.BAR_ORIGIN_Y);
        this.getGlobalData().objManager().saveObject(groupObj);
        this.addChild(groupObj,this.children.length);


        var len: number=this.curve.y.length;
        var step=this.getStep(false);

        // 纵轴
        if(app.y.axis.v==1) {
            var cp: CompoundPath=new CompoundPath();
            var path: PointPath=new PointPath();
            cp.paths.push(path);
            path.points.push(new Point(0,0,Point.POD_TT_PRIM_MOVE));
            path.points.push(new Point(0,-groupObj.pos.h,Point.POD_TT_PRIM_LINE));

            // 纵轴建立图形对象
            var graphObj: GraphObj=new GraphObj(this.getGlobalData());
            graphObj.pos=new ObjPosition(0,0,this.pos.w,this.pos.h);
            graphObj.cp=cp;
            graphObj.strokewidth=app.y.axis.w;
            graphObj.strokecolor=app.y.axis.color;
            this.getGlobalData().objManager().saveObject(graphObj);
            groupObj.addChild(graphObj,groupObj.children.length);

            // 尖头
            //        var path: PointPath=new PointPath();
            //        cp.paths.push(path);
            //        path.points.push(new Point(0,ChartObj.V_BAR_Y_START,Point.POD_TT_PRIM_MOVE));
            //        path.points.push(new Point(-5,ChartObj.V_BAR_Y_START+10,Point.POD_TT_PRIM_LINE));
            //
            //        var path: PointPath=new PointPath();
            //        cp.paths.push(path);
            //        path.points.push(new Point(0,ChartObj.V_BAR_Y_START,Point.POD_TT_PRIM_MOVE));
            //        path.points.push(new Point(5,ChartObj.V_BAR_Y_START+10,Point.POD_TT_PRIM_LINE));

        }


        // 大刻度建立文字对象
        for(var i=0;i<len;i++) {
            var textObj: TextObj=new TextObj(this.getGlobalData());
            //textObj.pos=new ObjPosition(-ChartObj.V_BAR_CURVE_TEXT_GAP,-(i+1)*step,this.pos.w/2,50);// this.pos.w,this.pos.h
            textObj.pos=new ObjPosition(-this.pos.w/2-ChartObj.V_BAR_CURVE_TEXT_GAP*2,-(i+1)*step,this.pos.w/2,50);
            textObj.te=this.curve.y[i].trim();
            textObj.fs=app.font_style.fs;
            textObj.fn=app.font_style.fn;
            textObj.fz=TextObj.FONT_ZOOM_FACTOR;
            textObj.po=TextObj.POSITION_RIGHT;
            textObj.color=app.font_style.color;
            this.getGlobalData().objManager().saveObject(textObj);
            groupObj.addChild(textObj,groupObj.children.length);
        }

        //        // y轴名称
        //        if(this.yName) {
        //            var textObj: TextObj=new TextObj(this.getGlobalData());
        //            textObj.pos=new ObjPosition(-ChartObj.V_BAR_CURVE_TEXT_GAP,-groupObj.pos.h-2*app.font_style.fs,this.pos.w/2,50);// this.pos.w,this.pos.h
        //            textObj.te=this.yName;
        //            textObj.fs=app.font_style.fs;
        //            textObj.fn=app.font_style.fn;
        //            textObj.fz=TextObj.FONT_ZOOM_FACTOR;
        //            textObj.color=app.font_style.color;
        //            this.getGlobalData().objManager().saveObject(textObj);
        //            groupObj.addChild(textObj,groupObj.children.length);
        //        }


        // 大刻度和辅助线
        if(app.x.axis_assist.v==1) {
            var cp: CompoundPath=new CompoundPath();
            for(var i=0;i<len;i++) {
                //            var path: PointPath=new PointPath();
                //            cp.paths.push(path);
                //            path.points.push(new Point(0, -(i+1)*step, Point.POD_TT_PRIM_MOVE));
                //            path.points.push(new Point(ChartObj.MARK_LEN, -(i+1)*step, Point.POD_TT_PRIM_MOVE));

                // 水平虚线
                var paths: Array<PointPath>=this.dashLineH(-(i+1)*step,
                    groupObj.pos.w,
                    5,
                    5);
                cp.paths=cp.paths.concat(paths);
            }

            // 建立图形对象
            var graphObj: GraphObj=new GraphObj(this.getGlobalData());
            graphObj.pos=new ObjPosition(0,0,this.pos.w,this.pos.h);
            graphObj.cp=cp;
            graphObj.strokewidth=app.x.axis_assist.w;
            graphObj.strokecolor=app.x.axis_assist.color;
            this.getGlobalData().objManager().saveObject(graphObj);
            groupObj.addChild(graphObj,groupObj.children.length);

        }
    }


    // 将x、y值映射到格子上
    public mappingXY(isX: Boolean=true,dataGroupIndex: number=0,isBar: Boolean=false): Array<number> {
        var ret: Array<number>=new Array<number>();


        var targetCurve: Array<string>=isX? this.curve.x:this.curve.y;
        var targetDataGroup: Array<string>=isX? this.dataGroups[dataGroupIndex].x:this.dataGroups[dataGroupIndex].y;


        // 是否为全数字
        if(isX) {
            // 将数据直接映射到step的整数倍上
            var len=targetCurve.length+1;
            for(var p=0;p<len;p++) {
                ret.push((p+1)/len);
            }

        } else {
            // 按刻度计算
            var maxY: number=parseFloat(targetCurve[targetCurve.length-1]);
            for(var j in targetDataGroup) {
                var data: number=parseFloat(targetDataGroup[j]);
                ret.push(data/maxY);
            }
        }

        return ret;
    }

    //        折线1
    public createLine() {
        var app: ChartApperanceLine=<ChartApperanceLine>this.apperance;
        if(!app) return;

        // 创建编组，起点为坐标轴原点,宽度为坐标轴长度
        var groupObj: GroupObj=new GroupObj(this.getGlobalData());
        groupObj.pos=new ObjPosition(ChartObj.BAR_ORIGIN_X,this.pos.h+ChartObj.BAR_ORIGIN_Y,
            this.pos.w+ChartObj.H_BAR_X_END-ChartObj.BAR_ORIGIN_X,this.pos.h+ChartObj.V_BAR_Y_END+ChartObj.BAR_ORIGIN_Y);
        this.getGlobalData().objManager().saveObject(groupObj);
        this.addChild(groupObj,this.children.length);

        // 获取颜色
        var clr: FColor=<FColor>(app.getColor(0));

        // 纵轴图形对象，方便描绘，注意对象点坐标轴向右向下
        var cp: CompoundPath=new CompoundPath();
        var graphObj: GraphObj=new GraphObj(this.getGlobalData());
        graphObj.pos=new ObjPosition(0,0,this.pos.w,this.pos.h);
        graphObj.cp=cp;
        graphObj.strokewidth=ChartObj.LINE_STROKE_WIDTH;
        graphObj.strokecolor=clr;
        graphObj.color=null;
        this.getGlobalData().objManager().saveObject(graphObj);
        groupObj.addChild(graphObj,groupObj.children.length);

        // 将x、y值映射到格子上
        var mapX: Array<number>=this.mappingXY(true,0);
        var mapY: Array<number>=this.mappingXY(false,0);

        // 将x轴进行数据转换
        // 将y轴进行数据转换
        var axisLenX: number=this.getAxisLen(true);
        var axisLenY: number=this.getAxisLen(false);

        var lenX: number=mapX.length;
        for(var i in mapX) {
            if(mapX[i]!=null) {
                mapX[i]*=axisLenX;
            }
        }
        var lenY: number=mapY.length;
        for(var j in mapY) {
            if(mapY[j]!=null) {
                mapY[j]*=axisLenY;
            }
        }
        // 划线
        var path: PointPath=new PointPath();
        cp.paths.push(path);
        var len=lenX<lenY? lenX:lenY;
        for(var k=0;k<len;k++) {
            var x_: number=mapX[k];
            var y_: number=mapY[k];
            if(x_==null||y_==null) {
                continue;
            }
            // 划线
            if(path.points.length==0) {
                path.points.push(new Point(x_,-y_,Point.POD_TT_PRIM_MOVE));
            } else {
                path.points.push(new Point(x_,-y_,Point.POD_TT_PRIM_LINE));
            }
        }


        // 创建画坐标点上的图形对象
        var cp: CompoundPath=new CompoundPath();
        var graphObj: GraphObj=new GraphObj();
        graphObj.pos=new ObjPosition(0,0,ChartObj.LINE_POINT_CIRCLE_WIDTH,ChartObj.LINE_POINT_CIRCLE_WIDTH);
        graphObj.cp=cp;
        //graphObj.color=(this.color? (<FColorBase>(this.color.deepCloneObject())):this.color);
        graphObj.color=clr;
        this.getGlobalData().objManager().saveObject(graphObj);
        groupObj.addChild(graphObj,groupObj.children.length);

        // 画坐标点
        var path: PointPath=new PointPath();
        cp.paths.push(path);
        var len=lenX<lenY? lenX:lenY;
        for(var k=0;k<len;k++) {
            var x_: number=mapX[k];
            var y_: number=mapY[k];
            if(x_==null||y_==null) {
                continue;
            }
            var c: CompoundPath=CommonUtil.createCompoundPath(CommonUtil.COMPOUNDPATH_CIRCLE,
                ChartObj.LINE_POINT_CIRCLE_WIDTH,ChartObj.LINE_POINT_CIRCLE_WIDTH);
            c.adjustPosition(x_-ChartObj.LINE_POINT_CIRCLE_WIDTH/2,-y_-ChartObj.LINE_POINT_CIRCLE_WIDTH/2,1);
            cp.paths.push(c.paths[0]);
        }
    }
    //        柱状图
    //        柱状图标注
    public createBar() {
        var app: ChartApperanceBar=<ChartApperanceBar>this.apperance;
        if(!app) return;

        // 创建编组，起点为坐标轴原点,宽度为坐标轴长度
        var groupObj: GroupObj=new GroupObj(this.getGlobalData());
        groupObj.pos=new ObjPosition(ChartObj.BAR_ORIGIN_X,this.pos.h+ChartObj.BAR_ORIGIN_Y,
            this.pos.w+ChartObj.H_BAR_X_END-ChartObj.BAR_ORIGIN_X,this.pos.h+ChartObj.V_BAR_Y_END+ChartObj.BAR_ORIGIN_Y);
        this.getGlobalData().objManager().saveObject(groupObj);
        this.addChild(groupObj,this.children.length);

        // 获取颜色
        var clr: FColor=<FColor>(app.getColor(0));


        // 纵轴图形对象，方便描绘，注意对象点坐标轴向右向下
        var cp: CompoundPath=new CompoundPath();
        var graphObj: GraphObj=new GraphObj(this.getGlobalData());
        graphObj.pos=new ObjPosition(0,0,this.pos.w,this.pos.h);
        graphObj.cp=cp;
        graphObj.color=clr;
        this.getGlobalData().objManager().saveObject(graphObj);
        groupObj.addChild(graphObj,groupObj.children.length);

        // 将x、y值映射到格子上
        var mapX: Array<number>=this.mappingXY(true,0,true);
        var mapY: Array<number>=this.mappingXY(false,0);

        // 将x轴进行数据转换
        // 将y轴进行数据转换
        var axisLenX: number=this.getAxisLen(true);
        var axisLenY: number=this.getAxisLen(false);



        var lenX: number=mapX.length;
        for(var i in mapX) {
            if(mapX[i]!=null) {
                mapX[i]*=axisLenX;
            }
        }
        var lenY: number=mapY.length;
        for(var j in mapY) {
            if(mapY[j]!=null) {
                mapY[j]*=axisLenY;
            }
        }

        // 获取bar的起点和宽度
        var len=lenX<lenY? lenX:lenY;
        var len=lenX;
        var bars: Array<ObjPosition>=app.calcBars(mapX[len-1],len,1,0);


        // 加入图形对象
        var stepX=this.getStep(true);
        for(var k=0;k<len;k++) {
            var x_: number=mapX[k];
            var y_: number=mapY[k];
            if(x_==null||y_==null) {
                continue;
            }
            // 每个值一个柱子
            var c: CompoundPath=CommonUtil.createCompoundPath(CommonUtil.COMPOUNDPATH_RECT,
                bars[k].w,y_);
            c.adjustPosition(bars[k].x+stepX/2,-y_,1);
            cp.paths.push(c.paths[0]);
        }
    }

    // 贝赛尔曲线插值
    // 参数：t, 0-1
    // 参数：p0\p1\p2\p3, 贝赛尔曲线
    // 返回：返回7个元素的数组表示发生了插入
    public insertPtToBezier(t: number,P0: Point,P1: Point,P2: Point,P3: Point): Array<Point> {
        /*
         * Say you want to insert a knot at a fraction t of the parameter space
         * inside the Bézier curve defined by P0, P1, P2, P3. Here's what you do:
         P0_1 = (1-t)*P0 + t*P1
         P1_2 = (1-t)*P1 + t*P2
         P2_3 = (1-t)*P2 + t*P3

         P01_12 = (1-t)*P0_1 + t*P1_2
         P12_23 = (1-t)*P1_2 + t*P2_3

         P0112_1223 = (1-t)*P01_12 + t*P12_23

         Then your first Bézier will be defined by:
         P0, P0_1, P01_12, P0112_1223;

         your second Bézier is defined by:
         P0112_1223, P12_23, P2_3, P3.
         */
        var P0_1: Point=new Point();
        var P1_2: Point=new Point();
        var P2_3: Point=new Point();
        var P01_12: Point=new Point();
        var P12_23: Point=new Point();
        var P0112_1223: Point=new Point();

        P0_1.x=(1-t)*P0.x+t*P1.x;
        P1_2.x=(1-t)*P1.x+t*P2.x;
        P2_3.x=(1-t)*P2.x+t*P3.x;
        P01_12.x=(1-t)*P0_1.x+t*P1_2.x;
        P12_23.x=(1-t)*P1_2.x+t*P2_3.x;
        P0112_1223.x=(1-t)*P01_12.x+t*P12_23.x;

        P0_1.y=(1-t)*P0.y+t*P1.y;
        P1_2.y=(1-t)*P1.y+t*P2.y;
        P2_3.y=(1-t)*P2.y+t*P3.y;
        P01_12.y=(1-t)*P0_1.y+t*P1_2.y;
        P12_23.y=(1-t)*P1_2.y+t*P2_3.y;
        P0112_1223.y=(1-t)*P01_12.y+t*P12_23.y;

        P0.type=Point.POD_TT_PRIM_LINE;
        P0_1.type=Point.POD_TT_PRIM_CSPLINE;
        P01_12.type=Point.POD_TT_PRIM_CSPLINE;
        P0112_1223.type=Point.POD_TT_PRIM_CSPLINE;
        P12_23.type=Point.POD_TT_PRIM_CSPLINE;
        P2_3.type=Point.POD_TT_PRIM_CSPLINE;
        P3.type=Point.POD_TT_PRIM_CSPLINE;

        return [P0,P0_1,P01_12,P0112_1223,P12_23,P2_3,P3];
    }

    // 计算扇形圆的直径
    public getPieRadius(): number {
        //        var PIE_W=this.pos.w-ChartObj.SECTOR_MARGIN*2;
        //        var PIE_H=this.pos.h-ChartObj.SECTOR_MARGIN*2;
        //        var PIE_SIZE=PIE_W<PIE_H? PIE_W:PIE_H;
        //        PIE_SIZE=PIE_SIZE>ChartObj.SECTOR_MIN_R? PIE_SIZE:ChartObj.SECTOR_MIN_R;
        //        return PIE_SIZE;
        //
        var bottomGap: number=10;
        var pieW: number=this.pos.w;
        var pieH: number=this.pos.h-ChartObj.NAME_Y-ChartObj.NAME_H+ChartObj.FROM_Y-bottomGap;
        var pieSize: number=(pieW<pieH)? pieW:pieH;
        return pieSize;
    }
    // 计算扇形圆轮廓
    public getPieCircle(minus: number=0): PointPath {
        var PIE_SIZE: number=this.getPieRadius()-minus;

        var circle: PointPath=CommonUtil.createCompoundPath(CommonUtil.COMPOUNDPATH_CIRCLE,PIE_SIZE,PIE_SIZE).paths[0];
        circle.adjustPosition(-PIE_SIZE/2,-PIE_SIZE/2,1);
        return circle;
    }
    // 计算扇形
    public calcSectorFromRightHorizionToEnd(ratioNumOfEnd: number): PointPath {
        var PIE_SIZE: number=this.getPieRadius();
        var circle: PointPath=this.getPieCircle();
        var insertIndex: Array<number>=new Array<number>();
        var f: number=ratioNumOfEnd;

        var path: PointPath=new PointPath();
        path.points.push(new Point(0,0,Point.POD_TT_PRIM_MOVE));
        /*
         *    第3象限          第4象限
         *
         *              o------------>
         *              |
         *    第2象限    |     第1象限
         *              |
         *              V
         */
        if(f<=1/4) {
        // 第1象限
            var pts: Array<Point>=this.insertPtToBezier(f*4.0,circle.points[3],circle.points[4],circle.points[5],circle.points[6]);
            pts[0].type=Point.POD_TT_PRIM_LINE; // 改变贝赛尔起点的类型
            path.points.push(Point.copy(pts[0]),Point.copy(pts[1]),Point.copy(pts[2]),Point.copy(pts[3]));

        } else if(f<=1/2) {
            // 第2象限
            var pts: Array<Point>=this.insertPtToBezier((f-1/4)*4.0,circle.points[6],circle.points[7],circle.points[8],circle.points[9]);
            circle.points[3].type=Point.POD_TT_PRIM_LINE; // 改变贝赛尔起点的类型
            path.points.push(Point.copy(circle.points[3]),Point.copy(circle.points[4]),Point.copy(circle.points[5]),Point.copy(circle.points[6]));
            path.points.push(Point.copy(pts[1]),Point.copy(pts[2]),Point.copy(pts[3]));

        } else if(f<=3/4) {
            // 第3象限
            var pts: Array<Point>=this.insertPtToBezier((f-1/2)*4.0,circle.points[9],circle.points[10],circle.points[11],circle.points[12]);
            circle.points[3].type=Point.POD_TT_PRIM_LINE; // 改变贝赛尔起点的类型
            path.points.push(Point.copy(circle.points[3]),Point.copy(circle.points[4]),Point.copy(circle.points[5]),Point.copy(circle.points[6]));
            path.points.push(Point.copy(circle.points[7]),Point.copy(circle.points[8]),Point.copy(circle.points[9]));
            path.points.push(Point.copy(pts[1]),Point.copy(pts[2]),Point.copy(pts[3]));

        } else {
            // 第4象限
            var pts: Array<Point>=this.insertPtToBezier((f-3/4)*4.0,circle.points[0],circle.points[1],circle.points[2],circle.points[3]);
            circle.points[3].type=Point.POD_TT_PRIM_LINE; // 改变贝赛尔起点的类型
            path.points.push(Point.copy(circle.points[3]),Point.copy(circle.points[4]),Point.copy(circle.points[5]),Point.copy(circle.points[6]));
            path.points.push(Point.copy(circle.points[7]),Point.copy(circle.points[8]),Point.copy(circle.points[9]));
            path.points.push(Point.copy(circle.points[10]),Point.copy(circle.points[11]),Point.copy(circle.points[12]));
            path.points.push(Point.copy(pts[1]),Point.copy(pts[2]),Point.copy(pts[3]));
        }
        path.points.push(new Point(0,0,Point.POD_TT_PRIM_CLOSE));

        return path;
    }
    // 计算扇形
    public calcSector(ratioNumOfEnd: Array<number>): Array<PointPath> {

        var ret: Array<PointPath>=new Array<PointPath>();

        for(var i=0;i<ratioNumOfEnd.length;i++) {
            var f: number=ratioNumOfEnd[i];
            var sectorPath: PointPath=this.calcSectorFromRightHorizionToEnd(f);
            ret.push(sectorPath);
        }

        return ret;
    }

    // 计算与圆的交点
    public calcIntersectFromRightHorizionToEnd(f: number): Point {
        var circle: PointPath=this.getPieCircle();
        if(f<1/4) {
            // 第1象限
            var pts: Array<Point>=this.insertPtToBezier(f,circle.points[3],circle.points[4],circle.points[5],circle.points[6]);
            return pts[3];

        } else if(f<1/2) {
            // 第2象限

            var pts: Array<Point>=this.insertPtToBezier(f-1/4,circle.points[6],circle.points[7],circle.points[8],circle.points[9]);
            return pts[3];

        } else if(f<3/4) {
            // 第3象限
            var pts: Array<Point>=this.insertPtToBezier(f-1/2,circle.points[9],circle.points[10],circle.points[11],circle.points[12]);
            return pts[3];

        } else {
            // 第4象限
            var pts: Array<Point>=this.insertPtToBezier(f-3/4,circle.points[0],circle.points[1],circle.points[2],circle.points[3]);
            return pts[3];
        }

    }
    // 计算与圆的交点
    public calcIntersect(ratioNumOfMiddle: Array<number>): Array<Point> {
        var ret: Array<Point>=new Array<Point>();

        for(var i=0;i<ratioNumOfMiddle.length;i++) {
            var f: number=ratioNumOfMiddle[i];
            var pt: Point=this.calcIntersectFromRightHorizionToEnd(f);
            ret.push(pt);
        }

        return ret;
    }
    // 获取颜色
    public getDefaultColor(): FColor {
        // 获取颜色
        var clr: FColor=null;
        if(this.color) {
            clr=<FColor>this.color;
        } else {
            clr=FColor.orangeColor(); // 没有颜色时，默认灰色
        }
        return clr;
    }



    //        饼状图
    //        饼状图标注
    public createPie() {
        var app: ChartApperancePie=<ChartApperancePie>this.apperance;
        if(!app) return;

        if(this.dataGroups.length==0||this.dataGroups[0].x.length==0
            ||this.dataGroups[0].y.length==0) {
            return;
        }

        // 如果个数是1，则圆形
        var categoryColors: Array<FColorBase>=new Array<FColorBase>(); // 分类的颜色
        var pieSize: number=this.getPieRadius();
        if(this.dataGroups[0].x.length==1) {
            var c: CompoundPath=CommonUtil.createCompoundPath(CommonUtil.COMPOUNDPATH_CIRCLE,
                pieSize,pieSize);
            c.adjustPosition(-pieSize/2,-pieSize/2,1);

            var graphObj: GraphObj=new GraphObj();
            graphObj.pos=new ObjPosition(this.pos.w/2,ChartObj.NAME_Y+ChartObj.NAME_H+pieSize/2,pieSize,pieSize);
            graphObj.cp=c;
            graphObj.color=app.getColor(0);
            this.getGlobalData().objManager().saveObject(graphObj);
            this.addChild(graphObj,this.children.length);

            // 纪录分类的颜色
            categoryColors.push(graphObj.color);
        } else {
            // 否则，都是扇形
            // 计算比例
            var category: Array<string>=this.dataGroups[0].x;
            var ratio: Array<string>=this.dataGroups[0].y;

            // 转换成数字
            var ratioNum: Array<number>=new Array<number>();
            for(var i in ratio) {
                var r: string=ratio[i];
                r=r.trim();
                if(!(/^[\d.]+$/.test(r))) {
                    ratioNum.push(0);
                } else {
                    ratioNum.push(+r);
                }
            }

            // 转换成百分比
            var total: number=0;
            ratioNum.forEach(function(value: number,index: number,array: number[]) {
                total+=value;
            });
            ratioNum.forEach(function(value: number,index: number,array: number[]) {
                array[index]=+(value/total).toFixed(2);
            });
            // 以向右的水平线为起点，顺时针画扇形区域，
            var ratioNumOfEnd: Array<number>=new Array<number>(); // 每个扇形区域的结束位置
            var ratioNumOfMiddle: Array<number>=new Array<number>(); // 每个扇形区域弧线的中间位置
            ratioNum.forEach(function(value: number,index: number,array: number[]) {
                // 扇形的结束位置
                if(index==0) {
                    ratioNumOfEnd.push(array[index]);
                } else {
                    ratioNumOfEnd.push(ratioNumOfEnd[index-1]+array[index]);
                }
                // 扇形的中间位置
                ratioNumOfMiddle.push(ratioNumOfEnd[index]-array[index]/2);
            });
            // 修正最后一个到 1
            ratioNumOfEnd[ratioNumOfEnd.length-1]=1;

            // 计算扇形
            var sectorPath: Array<PointPath>=this.calcSector(ratioNumOfEnd);

            // 以圆心为中心点建立图形对象
            for(var k=sectorPath.length-1;k>=0;k--) {
                var cp: CompoundPath=new CompoundPath();
                cp.paths.push(sectorPath[k]);

                var graphObj: GraphObj=new GraphObj();
                graphObj.pos=new ObjPosition(this.pos.w/2,ChartObj.NAME_Y+ChartObj.NAME_H+pieSize/2,pieSize,pieSize);
                graphObj.cp=cp;
                graphObj.color=app.getColor(k);
                graphObj.strokecolor=FColor.whiteColor();
                graphObj.strokewidth=ChartObj.SECTOR_SEP_STROKE_WIDTH;// 扇形之间
                this.getGlobalData().objManager().saveObject(graphObj);
                this.addChild(graphObj,this.children.length);

                // 纪录分类的颜色
                categoryColors.splice(0,0,graphObj.color);
            }
        }

        // 创建分类的说明
        this.createCategory(this.dataGroups[0].x,categoryColors)
    }

    //  分类备注
    public createCategory(category: Array<string>,categoryColors: Array<FColorBase>) {
        var app: ChartApperancePie=<ChartApperancePie>this.apperance;
        if(!app) return;


        var pieSize: number=this.getPieRadius();
        var curX: number=this.pos.w/2+pieSize/2+ChartObj.SECTOR_CATEGORY_GAP;
        var curY: number=ChartObj.NAME_Y+ChartObj.NAME_H;

        for(var i=0;i<category.length;i++) {
            // 色块
            var graphObj: GraphObj=new GraphObj(this.getGlobalData());
            graphObj.pos=new ObjPosition(curX,curY,
                ChartObj.SECTOR_CATEGORY_RECT_WIDTH,ChartObj.SECTOR_CATEGORY_RECT_WIDTH);
            graphObj.cp=CommonUtil.createCompoundPath(CommonUtil.COMPOUNDPATH_RECT,
                ChartObj.SECTOR_CATEGORY_RECT_WIDTH,ChartObj.SECTOR_CATEGORY_RECT_WIDTH);
            graphObj.color=categoryColors[i];//FColor.lightGrayColor();//
            this.getGlobalData().objManager().saveObject(graphObj);
            this.addChild(graphObj,this.children.length);

            // 文字
            var textObj: TextObj=new TextObj(this.getGlobalData());
            textObj.pos=new ObjPosition(
                curX+ChartObj.SECTOR_CATEGORY_RECT_WIDTH+ChartObj.SECTOR_CATEGORY_RECT_TEXT_GAP,
                curY,pieSize,50);// pieSize,pieSize
            textObj.te=category[i].trim();
            textObj.fs=app.font_style.fs;
            textObj.fz=TextObj.FONT_ZOOM_FACTOR;
            textObj.color=app.font_style.color;
            this.getGlobalData().objManager().saveObject(textObj);
            this.addChild(textObj,this.children.length);

            // 累加y
            curY+=(ChartObj.SECTOR_CATEGORY_LINE_SPACE+textObj.fs);

        }


    }
    // 数据来源
    public createFrom() {

        //        if(this.from){
        //            var textObj: TextObj=new TextObj();
        //            //textObj.pos = new ObjPosition(this.pos.w / 2 - this.from.length / 2 * textObj.fs,this.pos.h + ChartObj.FROM_Y,this.pos.w,this.pos.h);
        //            textObj.pos = new ObjPosition(0,this.pos.h+ChartObj.FROM_Y,this.pos.w,50);// this.pos.w,this.pos.h
        //            textObj.po = TextObj.POSITION_CENTER;// 水平居中
        //            textObj.te=this.from;
        //            textObj.fn=this.apperance.font_style.fn;
        //            textObj.fs=this.apperance.font_style.fs;
        //            textObj.fz=TextObj.FONT_ZOOM_FACTOR;
        //            textObj.color=this.apperance.font_style.color;
        //            this.getGlobalData().objManager().saveObject(textObj);
        //            this.addChild(textObj,this.children.length);
        //        }
    }
    // 名称
    public createName() {
        if(this.name) {
            var textObj: TextObj=new TextObj();
            //textObj.pos = new ObjPosition(this.pos.w/2-this.name.length/2*textObj.fs,ChartObj.NAME_Y,this.pos.w,this.pos.h);
            //textObj.pos=new ObjPosition(0,ChartObj.NAME_Y,this.pos.w,this.pos.h);
            textObj.pos=new ObjPosition(0,-40,this.pos.w,50);
            textObj.po=TextObj.POSITION_CENTER;// 水平居中
            textObj.te=this.name;
            textObj.fn=this.apperance.font_style.fn;
            textObj.fs=this.apperance.font_style.fs;
            textObj.fz=TextObj.FONT_ZOOM_FACTOR;
            textObj.color=this.apperance.font_style.color;
            this.getGlobalData().objManager().saveObject(textObj);
            this.addChild(textObj,this.children.length);
        }
    }

    // 删除数据组中末尾的空格
    private removeArrNullTail(arr: Array<string>) {
        var len: number=arr.length;
        for(var i=len-1;i>=0;i--) {
            var one: string=arr[i];
            if(!one||one.length==0) {
                arr.splice(i,1);
            } else {
                one=one.trim();
                break;
            }
        }
    }
    private preprocess() {
        this.removeArrNullTail(this.curve.x);
        this.removeArrNullTail(this.curve.y);

        for(var i in this.dataGroups) {
            var one: SJGXY=this.dataGroups[i];
            this.removeArrNullTail(one.x);
            this.removeArrNullTail(one.y);
        }

        // 从dataGroups中提取出纵轴刻度
        this.calcCurveXFromDataGroups();
        this.calcCurveYFromDataGroups();
    }
    // 从dataGroups中提取出横轴刻度
    private calcCurveXFromDataGroups() {
        this.curve.x.splice(0,this.curve.x.length);

        // 从Y中提取数字最大数字
        if(this.dataGroups.length!=1) return;
        var data=this.dataGroups[0];
        for(var i=0;i<data.x.length;i++) {
            this.curve.x.push(data.x[i]);
        }
    }
    // 从dataGroups中提取出纵轴刻度
    private calcCurveYFromDataGroups() {
        this.curve.y.splice(0,this.curve.y.length);

        // 从Y中提取数字最大数字
        if(this.dataGroups.length!=1) return;
        var data=this.dataGroups[0];
        var maxY=0;
        for(var i=0;i<data.y.length;i++) {
            var y=parseFloat(data.y[i]);
            maxY=(y>maxY)? y:maxY;
        }
        if(maxY==0) return;

        // 计算中间刻度［固定分成4段］
        var stepCount=4;
        var all=maxY;

        // 分段长度向上取整数，作为刻度的步长
        if(all>1) {
            // >1
            all=this.alignNumber(all);
        } else if(all>0) {
            // >0 && <1
            // 放大N倍，按step>1的逻辑处理，然后除以N倍
            var ns=(""+all);
            var s=ns.length-2;
            var p=Math.pow(10,s);
            var step_=this.alignNumber(all*p);
            all=step_/p;

        } else {
            // 1
            all=1;
        }

        // 纵轴小数点位数
        var fix=0;
        var str=""+all;
        var pos=str.indexOf(".");
        if(pos>0) {
            var intStr=str.substring(0,pos);
            var intLen=intStr.length;
            var subStr=str.substring(pos+1);
            var subLen=subStr.length;
            if(intStr.length>1) {// 大于等于10.0
                fix=0;
            } else if(intStr.length==1) {
                if(intStr[0]=="0") {// 小于1.0
                    fix=subLen<3? subLen:3;
                } else { //
                    fix=1;
                }
            }
        } else if(all<10) {
            fix=1;
        }

        // 计算纵轴数据
        var step=all/stepCount;
        for(var i=0;i<stepCount;i++) {
            var cy=((i+1)*step).toFixed(fix);
            this.curve.y.push(""+cy);
        }

    }
    // t > 1.0
    private alignNumber(t): number {
        // 如果是个位数，则向上对齐到整数个位
        // 如果是十位数，则向上对齐到整数个位
        // 如果是百位数，则向上对齐到整数十位
        // 如果是千位数，则向上对齐到整数百位
        // 以此类推
        var str=(""+t);
        var pos=str.indexOf('.');
        if(pos>0) {
            str=str.substring(0,pos);
        }
        var s=str.length;
        if(s==1) {
            t=Math.floor(1+parseInt(""+t%10));
        } else {
            t=Math.floor(1+parseInt(""+t/(Math.pow(10,s-2))))*Math.pow(10,s-2);
        }
        return t;
    }

    // 生成折线图
    public createLineChart() {
        this.createHorizonBar();
        this.createVerticalBar();
        this.createLine();
        this.createFrom();
        this.createName();
    }
    // 生成柱状图
    public createBarChart() {
        this.createHorizonBar();
        this.createVerticalBar();
        this.createBar();
        this.createFrom();
        this.createName();
    }
    // 生成饼状图
    public createPieChart() {
        this.createPie();
        this.createFrom();
        this.createName();
    }

    // 计算轮廓形状
    public refresh(replace: SJGReplaceGroup=null) {
        // 删除子
        this.removeAllChild();

        // 删除mask
        this.mask=null;
        // 删除数据组中末尾的空格
        this.preprocess();

        if(this.type==SJGReplaceItemBase.TYPE_LINE_CHART) {
            if(!this.apperance) {
                this.apperance=new ChartApperanceLine();
            }
            this.createLineChart();
        } else if(this.type==SJGReplaceItemBase.TYPE_BAR_CHART) {
            if(!this.apperance) {
                this.apperance=new ChartApperanceBar();
            }
            this.createBarChart();
        } else if(this.type==SJGReplaceItemBase.TYPE_PIE_CHART) {
            if(!this.apperance) {
                this.apperance=new ChartApperancePie();
            }
            this.createPieChart();


        }

    }

    // 深度更新id［处理自身和子对象，递归］
    // 参数：idMaps，新旧id的对应关系, 例如：[{oldId:1,newId:2}]
    public deepResetId(idMaps: Array<any>) {
        super.deepResetId(idMaps);

    }
    
//SJG_MARK_APPEND--------------------
    public copyInfo(replaceItemChart:SJGReplaceItemChart, versionId){
        //    图表名称
        this.name = replaceItemChart.name;
        //    x轴名称／y轴名称
        this.xName = replaceItemChart.xName;
        this.yName = replaceItemChart.yName;
        // 刻度线，当type为40折线图时有效
        this.curve=new SJGXY();
        this.curve.fromJson(replaceItemChart.curve,versionId);
        // 数据组
        this.dataGroups=new Array<SJGXY>();
        for(var i in replaceItemChart.dataGroups){
            var one:SJGXY = new SJGXY();
            one.fromJson(replaceItemChart.dataGroups[i],versionId);
            this.dataGroups.push(one);
        }
        //    数据源
        this.from= replaceItemChart.from;


        // 20160910 补丁start：1、对于旧版本的柱状图的datagroup的x不存在，需要将curve的x复制给datagroup的x
        if(this.type ==41){
            if(this.curve.x.length>0 && this.dataGroups.length>0){
                var data0 = this.dataGroups[0];
                if(data0.x.length==0){
                    for(var j=0;j<this.curve.x.length;j++){
                        data0.x.push(this.curve.x[j]);
                    }
                }
            }
        }
        // 补丁end

        // 20160911 补丁start：1、对于datagroup的x和y的长度不一致的问题，删除掉多余的部分
        if(this.dataGroups.length>0){
            var data0 = this.dataGroups[0];
            this.removeArrNullTail(data0.x);
            this.removeArrNullTail(data0.y);

            var xLen = data0.x.length;
            var yLen = data0.y.length;
            var min = xLen<yLen?xLen:yLen;
            if(xLen>min)    data0.x.splice(min);
            if(yLen>min)    data0.y.splice(min);
        }
        // 补丁end


    }

}//SJG_MARK_END-------------------------